package com.wxscrmplus.statistics.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.base.Joiner;
import com.wxscrmplus.customer.domain.CusMaintain;
import com.wxscrmplus.customer.domain.Customer;
import com.wxscrmplus.customer.domain.FollowUser;
import com.wxscrmplus.customer.domain.Opportunity;
import com.wxscrmplus.customer.mapper.CusMaintainMapper;
import com.wxscrmplus.customer.mapper.CustomerMapper;
import com.wxscrmplus.customer.mapper.FollowUserMapper;
import com.wxscrmplus.customer.mapper.OpportunityMapper;
import com.wxscrmplus.drainage.mapper.DraChannelMapper;
import com.wxscrmplus.statistics.service.ICustomerStatsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * 客户统计分析Service业务层处理
 *
 * @author 王永超
 * @date 2023-03-24
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class CustomerStatsServiceImpl implements ICustomerStatsService {

    private final CustomerMapper baseMapper;
    private final CusMaintainMapper maintainMapper;
    private final OpportunityMapper opportunityMapper;
    private final DraChannelMapper channelMapper;
    private final FollowUserMapper followUserMapper;

    /**
     * 刷新维护总成本
     */
    @Override
    public void refreshCostsByCustomerIds(Long customerId) {
        Customer update = new Customer();
        update.setCustomerId(customerId);
        QueryWrapper<CusMaintain> query = new QueryWrapper<>();
        query.select("COALESCE(sum(payment_slip),0) AS paymentSlip");
        query.lambda().eq(CusMaintain::getCustomerId, customerId);
        Map<String, Object> paymentSlipMap = maintainMapper.selectMaps(query).get(0);
        update.setMaintainCost(new BigDecimal(paymentSlipMap.get("paymentSlip").toString()));
        baseMapper.updateById(update);
    }

    /**
     * 刷新商机总金额
     */
    @Override
// 1084db5b20449169253eec34f949f37b
    public void refreshOpportunityAmountByCustomerIds(Long customerId) {
        Customer update = new Customer();
        update.setCustomerId(customerId);
        QueryWrapper<Opportunity> query = new QueryWrapper<>();
        query.select("COALESCE(sum(pay_amount),0) AS payAmount");
        query.lambda().eq(Opportunity::getCustomerId, customerId).eq(Opportunity::getSaleStage,
            Opportunity.SaleStageFieldEnums.YICHENGDAN.getValue());
        Map<String, Object> paymentSlipMap = opportunityMapper.selectMaps(query).get(0);
        update.setOpportunityAmount(new BigDecimal(paymentSlipMap.get("payAmount").toString()));
        baseMapper.updateById(update);
    }

    /**
     * 获取当天销售机会金额
     */
    @Override
    public BigDecimal getTodayOpportunityAmount(Long customerId) {
        QueryWrapper<Opportunity> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("COALESCE(sum(need_amount),0) AS needAmount");
        queryWrapper.lambda().eq(Opportunity::getCustomerId, customerId)
            .ne(Opportunity::getSaleStage, Opportunity.SaleStageFieldEnums.YICHENGDAN.getValue());
        queryWrapper.lambda().between(Opportunity::getPredictMakeTime,
            LocalDateTimeUtil.now().withHour(0).withMinute(0).withSecond(0), LocalDateTimeUtil.now().withHour(23).withMinute(59).withSecond(59));
        Map<String, Object> needAmountMap = opportunityMapper.selectMaps(queryWrapper).get(0);
        return new BigDecimal(needAmountMap.get("needAmount").toString());
    }

    /**
     * 获取客户总数量
     *
     * @return
     */
    @Override
    public long totalCustomer(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        QueryWrapper<Customer> wrapper = Wrappers.query();
        String delType = Joiner.on(",").join(Arrays.asList(FollowUser.DelTypeFieldEnums.ZERO.getValue(), FollowUser.DelTypeFieldEnums.ONE.getValue()));
        wrapper.inSql("customer_id", String.format("SELECT customer_id FROM `cus_follow_user` WHERE del_type IN(%s) AND user_id in(%s)",
            delType, Joiner.on(",").join(userIds)));
        return baseMapper.selectCount(wrapper);
    }

    /**
     * 流失客户总数
     *
     * @return
     */
    @Override
    public long lossCustomer(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        QueryWrapper<Customer> wrapper = Wrappers.query();
        String delType = Joiner.on(",").join(Arrays.asList(FollowUser.DelTypeFieldEnums.THREE.getValue(), FollowUser.DelTypeFieldEnums.TWO.getValue(), FollowUser.DelTypeFieldEnums.ONE.getValue()));
        wrapper.inSql("customer_id", String.format("SELECT customer_id FROM `cus_follow_user` WHERE del_type IN(%s) AND user_id in(%s)",
            delType, Joiner.on(",").join(userIds)));
        return baseMapper.selectCount(wrapper);
    }

    /**
     * 已成交商机总数
     *
     * @return
     */
    @Override
    public long totalOpportunity(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        return opportunityMapper.selectCount(Wrappers.query(new Opportunity()).lambda()
            .eq(Opportunity::getSaleStage, Opportunity.SaleStageFieldEnums.YICHENGDAN.getValue())
            .in(Opportunity::getSaleId, userIds));
    }

    /**
     * 总利润
     *
     * @return
     */
    @Override
    public BigDecimal totalProfit(List<Long> userIds) {
        return baseMapper.totalProfit(Joiner.on(",").join(userIds));
    }

    /**
     * 近12月总客户数量
     */
    @Override
    public List<Map<String, Object>> totalCustomerLast12Month(List<Long> userIds) {
        QueryWrapper<Customer> wrapper = Wrappers.query();
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        String delType = Joiner.on(",").join(Arrays.asList(FollowUser.DelTypeFieldEnums.ZERO.getValue(), FollowUser.DelTypeFieldEnums.ONE.getValue()));
        wrapper.lambda().eq(Customer::getDelFlag, 0);
        wrapper.inSql("customer_id", String.format("SELECT customer_id FROM `cus_follow_user` WHERE del_type IN(%s) AND user_id in(%s)",
            delType, Joiner.on(",").join(userIds)));
        return baseMapper.countLast12Month(wrapper);
    }

    /**
     * 近12月总流失客户数量
     */
    @Override
    public List<Map<String, Object>> lossCustomerLast12Month(List<Long> userIds) {
        QueryWrapper<Customer> wrapper = Wrappers.query();
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        String delType = Joiner.on(",").join(Arrays.asList(FollowUser.DelTypeFieldEnums.THREE.getValue(), FollowUser.DelTypeFieldEnums.TWO.getValue(), FollowUser.DelTypeFieldEnums.ONE.getValue()));
        wrapper.lambda().eq(Customer::getDelFlag, 0);
        wrapper.inSql("customer_id", String.format("SELECT customer_id FROM `cus_follow_user` WHERE del_type IN(%s) AND user_id in(%s)",
            delType, Joiner.on(",").join(userIds)));
        return baseMapper.countLast12Month(wrapper);
    }

    /**
     * 近12月总利润
     */
    @Override
    public List<Map<String, Object>> totalProfitLast12Month(List<Long> userIds) {
        /**
         * 利润=商机金额-维护开支-获客成本
         */
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        String customerIdSql = "SELECT customer_id FROM `cus_follow_user` WHERE user_id in (" + Joiner.on(",").join(userIds) + ")";
        List<Map<String, Object>> maintainList = maintainMapper.totalPaymentSlipMonth(Wrappers.query(new CusMaintain())
            .inSql("cus_maintain.customer_id", customerIdSql));
        List<Map<String, Object>> opportunityList = opportunityMapper.totalPayAmountLast12Month(Wrappers.query(new Opportunity())
            .inSql("cus_opportunity.customer_id", customerIdSql)
            .lambda().eq(Opportunity::getSaleStage, Opportunity.SaleStageFieldEnums.YICHENGDAN.getValue()));

        List<Map<String, Object>> winCostList = followUserMapper.totalWinCostLast12Month(Wrappers.query(new FollowUser()).lambda()
            .in(FollowUser::getUserId, userIds));
        List<Map<String, Object>> result = new ArrayList<>();
        for (int i = 0; i < maintainList.size(); i++) {
            String month = maintainList.get(i).get("month").toString();
            BigDecimal opportunityAmount = new BigDecimal(opportunityList.get(i).get("count").toString());
            BigDecimal maintainCost = new BigDecimal(maintainList.get(i).get("count").toString());
            BigDecimal draCustomerCost = new BigDecimal(winCostList.get(i).get("count").toString());
            result.add(new HashMap<String, Object>() {{
                put("month", month);
                put("count", opportunityAmount.subtract(maintainCost).subtract(draCustomerCost));
            }});
        }
        return result;
    }

    /**
     * 近12月总已成交商机数量
     */
    @Override
    public List<Map<String, Object>> totalOpportunityLast12Month(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            userIds = Collections.singletonList(-1L);
        }
        return opportunityMapper.countLast12Month(Wrappers.query(new Opportunity()).lambda()
            .eq(Opportunity::getSaleStage, Opportunity.SaleStageFieldEnums.YICHENGDAN.getValue())
            .in(Opportunity::getSaleId, userIds));
    }

    @Override
    public List<Map<String, Object>> channelCustomerCount(List<Long> userIds) {
        return followUserMapper.channelCustomerCount(Joiner.on(",").join(userIds));
    }

    @Override
    public List<Map<String, Object>> cusTypeCustomerCount(List<Long> userIds) {
        List<Map<String, Object>> maps = followUserMapper.cusTypeCustomerCount(Joiner.on(",").join(userIds));
        return maps;
    }

    @Override
    public List<Map<String, Object>> barChartFollowStageCustomer(List<Long> userIds) {
        return baseMapper.countFollowStage(Joiner.on(",").join(userIds));
    }
}
